package com.ybkj.daijia.server.service.impl;

import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.config.PassengerApi;
import com.ybkj.daijia.config.SmsApi;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.Pageable;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.page.impl.PageRequest;
import com.ybkj.daijia.server.event.model.MemberNoticeEvent;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mapper.MemberNoticeMapper;
import com.ybkj.daijia.server.mapper.NoticeXPassengerMapper;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.MemberNotice;
import com.ybkj.daijia.server.model.NoticeXPassenger;
import com.ybkj.daijia.server.service.MemberNoticeService;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * @author Shine
 */
@Service
public class DefaultMemberNoticeService implements MemberNoticeService {

    @Autowired
    private MemberNoticeMapper memberNoticeMapper;


    @Autowired
    private NoticeXPassengerMapper noticeXPassengerMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @Autowired
    private PassengerApi passengerApi;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private SmsApi smsApi;

    /* (non-Javadoc)
     * @see com.ybkj.shop.service.AdminService#queryAll()
     */
    public Page<MemberNotice> queryAll() {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        }

        List<MemberNotice> content = memberNoticeMapper.selectByPage(params);
        long total = memberNoticeMapper.countByPage(params);

        return new PageImpl<MemberNotice>(content, pageable, total);
    }

    @Transactional(rollbackFor = Exception.class)
    public MemberNotice insertRecord(MemberNotice memberNotice) {

        memberNoticeMapper.insertRecord(memberNotice);

        return memberNotice;

    }

    public MemberNotice findOne(Long id) {

        return memberNoticeMapper.selectByPrimaryKey(id);
    }

    @Override
    public Page<MemberNotice> findAll(String phone, Integer page, Integer limit) {

        Pageable pageable = new PageRequest(page, limit);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", page * limit);
        params.put("size", limit);

        List<MemberNotice> content = memberNoticeMapper.selectByPage(params);
        long total = memberNoticeMapper.countByPage(params);

        return new PageImpl<MemberNotice>(content, pageable, total);

    }

    @Transactional(rollbackFor = Exception.class)
    public void delete(MemberNotice memberNotice) {

        noticeXPassengerMapper.deleteByNotice(memberNotice.getId());
        memberNoticeMapper.deleteByPrimaryKey(memberNotice.getId());

    }

    @Override
    public Page<Map<String, Object>> pageNotice(Passenger passenger, Integer page, Integer limit) {

        Setting setting = settingUtils.get();

        Pageable pageable = new PageRequest(page, limit);

        List<NoticeXPassenger> content = noticeXPassengerMapper
            .selectByPassenger(passenger.getId(), page * limit, limit);
        long total = noticeXPassengerMapper.countByPassenger(passenger.getId());

        List<Map<String, Object>> dataMapList = new ArrayList<Map<String, Object>>();
        if (total > 0) {
            for (NoticeXPassenger noticeXPassenger : content) {
                MemberNotice memberNotice = memberNoticeMapper
                    .selectByPrimaryKey(noticeXPassenger.getNoticeId());

                Map<String, Object> dataMap = new HashMap<String, Object>();
                dataMap.put("id", memberNotice.getId());
                dataMap.put("content", memberNotice.getContent());
                dataMap.put("hasRead", noticeXPassenger.isHasRead());
                dataMap.put("created", noticeXPassenger.getCreated().getTime());
                if (StringUtils.isNotBlank(memberNotice.getContentMore())) {
                    String url =
                        setting.getWebUrl() + "/member/api/rest/v3/viewNotice/" + memberNotice
                            .getId();
                    dataMap.put("url", url);
                } else {
                    dataMap.put("url", null);
                }
                dataMapList.add(dataMap);

            }
        }

        return new PageImpl<Map<String, Object>>(dataMapList, pageable, total);

    }

    @Override
    public void create(String content, String contentMore, String carNumber, String name,
        String phone, Long[] companyIds, String startTime, String endTime,
        Long[] gradeIds, Integer[] type, Boolean[] allowOverdraw, String[] channelName,
        String sendTypes) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        if (principal.isCompanyType()) {
            if (null == companyIds) {
                List<Company> companylist = companyMapper.selectAll();
                companyIds = new Long[companylist.size()];
                for (int i = 0; i < companylist.size(); i++) {
                    companyIds[i] = companylist.get(i).getId();
                }
            }
        } else {
            companyIds = new Long[1];
            companyIds[0] = principal.getCompanyId();
        }

        MemberNotice memberNotice = null;
        if (sendTypes.contains("message")) {
            memberNotice = new MemberNotice();
            memberNotice.setCompanyId(principal.getCompanyId());
            memberNotice.setContent(content);
            memberNotice.setContentMore(contentMore);
            memberNotice.setOperating(principal.getUsername());
            memberNoticeMapper.insertRecord(memberNotice);
        }

        final Company mainCompany = companyMapper.selectMainCompany();

        for (int i = 0; i < companyIds.length; i++) {
            Long companyId = companyIds[i];
            Long[] realCompanyId = {companyId};

            Long count = passengerApi
                .countPassenger(principal, carNumber, name, phone, realCompanyId, startTime,
                    endTime, gradeIds, type, allowOverdraw, null);
            Integer rows = 1000;
            Integer totalPage = (int) (count / rows);
            if (count % rows != 0) {
                totalPage++;
            }
            Integer page = 0;
            if (totalPage > 0) {
                page = 1;
            }
            while (count > 0 && page <= totalPage) {
                final List<Passenger> passengerList = passengerApi
                    .findPassenger(principal, carNumber, name, phone, realCompanyId, startTime,
                        endTime, gradeIds, type, allowOverdraw, null, page, rows);
                final String sendTypesFinal = sendTypes;
                final String contentFinal = content;
                final MemberNotice memberNoticeFinal = memberNotice;
                final Setting setting = settingUtils.get();

                taskExecutor.execute(new Runnable() {
                    public void run() {

                        if (sendTypesFinal.contains("message")) {
                            if (!CollectionUtils.isEmpty(passengerList)) {
                                for (Passenger passenger : passengerList) {
                                    NoticeXPassenger noticeXPassenger = new NoticeXPassenger();
                                    noticeXPassenger.setPassengerId(passenger.getId());
                                    noticeXPassenger.setNoticeId(memberNoticeFinal.getId());
                                    noticeXPassenger.setHasRead(false);
                                    noticeXPassengerMapper.insertRecord(noticeXPassenger);
                                }
                                MemberNoticeEvent memberNoticeEvent = new MemberNoticeEvent(
                                    memberNoticeFinal, passengerList);
                                applicationEventMulticaster.multicastEvent(memberNoticeEvent);
                            }
                        }

                        if (sendTypesFinal.contains("sms")) {

                            if (!CollectionUtils.isEmpty(passengerList)) {
                                String url = "";
                                if (null != memberNoticeFinal && StringUtils
                                    .isNotBlank(memberNoticeFinal.getContentMore())) {
                                    url = setting.getWebUrl() + "/member/api/rest/v3/viewNotice/"
                                        + memberNoticeFinal.getId();
                                    try {
                                        url = HttpClientUtil.getShortUrl(url);
                                    } catch (UnsupportedEncodingException e) {
                                        e.printStackTrace();
                                    }
                                }
                                StringBuilder phones = new StringBuilder();
                                for (int i = 0; i < passengerList.size(); i++) {
                                    Passenger passenger = passengerList.get(i);
                                    phones.append(passenger.getPhone());
                                    if (i != passengerList.size() - 1) {
                                        phones.append(",");
                                    }
                                }

                                String signName = "";
                                if (setting.isSmsMainCompany()) {
                                    signName = mainCompany.getSignName();
                                } else {
                                    Company memberCompany = companyMapper
                                        .selectByPrimaryKey(passengerList.get(0).getCompanyId());
                                    signName = memberCompany.getSignName();
                                }

                                smsApi.batchSendSms(phones.toString(),
                                    contentFinal + url + "退订回复TD【" + signName + "】");
                            }
                        }
                    }
                });
                count = count - rows;
                page++;
            }
        }
    }
}
